package br.perfiman.service.impl;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import br.perfiman.dao.AbstractDAOService;
import br.perfiman.model.AbstractEntity;
import br.perfiman.service.AbstractService;
import br.perfiman.utils.FormUtils;

/**
 * Main implementation for PerFiMan's Bussiness Services
 *
 * @author Wagner Costa
 * @since 27/12/2007
 * @version 1.0
 *
 * @param <Entity>
 */
public abstract class AbstractServiceBean<Entity extends AbstractEntity> implements AbstractService<Entity>{
	protected AbstractDAOService<Entity> dao;

	public void setDao(AbstractDAOService<Entity> dao){
		this.dao = dao;
	}

	public AbstractServiceBean() {
		dao = getDao();
	}

	@SuppressWarnings("unchecked")
	private Class<Entity> getEntityClass() {
		return (Class<Entity>) ((ParameterizedType) getClass()
				.getGenericSuperclass()).getActualTypeArguments()[0];
    }

	/**
	 * Returns dao instance from subclass
	 *
	 * @author Wagner Costa
	 * @since 27/12/2007
	 * @version 1.0
	 * @return
	 */
	public abstract AbstractDAOService<Entity> getDao();

	public Entity insert(Entity entity) throws Exception {
		updateDao();
		return dao.insert(entity);
	}

	public void remove(Entity entity) throws Exception {
		updateDao();
		dao.remove(entity);
	}

	public List<Entity> retrieveAll() throws Exception {
		updateDao();
		return dao.retrieveAll();
	}

	public Entity retrieveById(Object id) throws Exception {
		updateDao();
		return dao.retrieveById(id);
	}

	public Entity update(Entity entity) throws Exception {
		updateDao();
		return dao.update(entity);
	}

	private void updateDao(){
		if(dao == null)
			dao = getDao();
	}

	//------------------------------ Validation Methods

	/**
	 * Returns the validation fields errors
	 *
	 * @author Wagner Costa
	 * @since 12/01/2008
	 * @version 1.0
	 * @param entity
	 * @param isUpdate
	 */
	public abstract void validateRequiredFields(Entity entity, boolean isUpdate);

	/**
	 * Returns the ivalid fields errors
	 *
	 * @author Wagner Costa
	 * @since 12/01/2008
	 * @version 1.0
	 * @param isUpdate
	 * @param entity
	 */
	public abstract void validateInvalidFields(Entity entity, boolean isUpdate);

	/**
	 * Returns the bussiness rules errors
	 *
	 * @author Wagner Costa
	 * @since 12/01/2008
	 * @version 1.0
	 * @param entity
	 * @param isUpdate
	 */
	public abstract void validateBussinessRules(Entity entity, boolean isUpdate);

	public String getFormKey(String property){
		return FormUtils.getFormKey(getEntityClass(), property);
	}
}
